package com.devenv.entity.base;

import jakarta.persistence.*;
import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

/**
 * 基础实体类
 * <p>
 * 包含审计字段，所有需要审计功能的实体都应该继承此类。
 * 提供自动的创建时间、更新时间、创建者、修改者、版本号和逻辑删除支持。
 * </p>
 * 
 * @author DevEnv OpenSource Team
 * @version 1.0.0
 * @since 1.0.0
 */
@Data
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 创建时间
     */
    @CreationTimestamp
    @Column(name = "created_at", nullable = false, updatable = false)
    private LocalDateTime createdAt;

    /**
     * 更新时间
     */
    @UpdateTimestamp
    @Column(name = "updated_at", nullable = false)
    private LocalDateTime updatedAt;

    /**
     * 创建者ID
     */
    @CreatedBy
    @Column(name = "created_by", updatable = false)
    private Long createdBy;

    /**
     * 最后修改者ID
     */
    @LastModifiedBy
    @Column(name = "updated_by")
    private Long updatedBy;

    /**
     * 版本号（乐观锁）
     */
    @Version
    @Column(name = "entity_version")
    private Long entityVersion;

    /**
     * 逻辑删除标志
     */
    @Column(name = "deleted", nullable = false)
    private Boolean deleted = false;

    /**
     * 备注
     */
    @Column(name = "remark", length = 500)
    private String remark;

    /**
     * 检查实体是否被逻辑删除
     */
    public boolean isDeleted() {
        return Boolean.TRUE.equals(deleted);
    }

    /**
     * 标记为已删除
     */
    public void markAsDeleted() {
        this.deleted = true;
    }

    /**
     * 恢复删除
     */
    public void restore() {
        this.deleted = false;
    }

    /**
     * 检查实体是否为新实体（未持久化）
     */
    public boolean isNew() {
        return id == null;
    }

    /**
     * 获取实体标识符的字符串表示
     */
    public String getIdAsString() {
        return id != null ? id.toString() : null;
    }
}
